#include <cctype>
#include <cstdint>
#include <iostream>
#include <utility>
#include <vector>
#include <map>
 
using ll = int64_t;
using std::cin, std::cout;
 
// 定义最大节点数为5e5加5，以确保足够的空间
const ll maxn = 5e5 + 5;
ll n, k;                      // n: 树的节点数，k: 暴龙的种类数
ll a[maxn];                   // a[i]: 第i个节点的暴龙种类
ll ans[maxn];                 // ans[i]: 第i种暴龙的红温值
std::vector<std::pair<ll, ll>> adj[maxn]; // adj[u]: 节点u的邻居及边权
std::map<ll, ll> dp[maxn];    // dp[u][j]: 节点u到子树中种类j的最大距离
 
// 优化输入读取，提高IO速度
struct CinNum {
    char c;
    ll n, w;
    // 重载右移运算符以自定义输入方式
    CinNum &operator>>(ll &num) {
        c = n = 0;
        w = 1;
        // 跳过非数字字符，记录负号
        while (!isdigit(c = getchar())) {
            if (c == '-') w = -1;
        }
        // 读取数字
        while (isdigit(c)) {
            n = n * 10 + (c - '0');
            c = getchar();
        }
        num = n * w;
        return *this;
    }
} cinn;
// 使用自定义的CinNum来替代标准输入
#define cin cinn
 
/**
 * @brief 使用深度优先搜索 (DFS) 计算每种暴龙的红温值
 *
 * @param fth 当前节点的父节点
 * @param u 当前处理的节点
 */
void dfs(const ll &fth, const ll &u) noexcept {
    // 初始化当前节点的dp，自己到自己距离为0
    dp[u].emplace(a[u], 0);
    
    // 遍历所有邻接节点
    for (const auto& [v, w] : adj[u]) {
        if (v == fth) continue; // 避免回到父节点
        dfs(u, v);              // 递归处理子节点
        
        // 遍历子节点v的所有暴龙种类及其对应的最大距离
        for (const auto& [kk, vv] : dp[v]) {
            // 如果当前节点u已经有这种暴龙类型，且子节点v也有
            if ((dp[u][kk] > 0 || a[u] == kk) && (dp[v][kk] > 0 || a[v] == kk)) {
                // 更新ans[kk]为u和v子树中这种暴龙类型的最大距离
                ans[kk] = std::max(ans[kk], dp[u][kk] + dp[v][kk] + w);
            }
            // 更新u节点到这种暴龙类型的最大距离
            dp[u][kk] = std::max(dp[u][kk], dp[v][kk] + w);
            
            // 如果当前节点u本身就是这种暴龙类型，进一步更新ans[kk]
            if (a[u] == kk) {
                ans[kk] = std::max(ans[kk], dp[u][kk]);
            }
        }
        // 清空子节点v的dp以节省内存，因为已经合并到u的dp中了
        dp[v].clear();
    }
}
 
int main(){
    // 读取节点数n和暴龙种类数k
    cin >> n >> k;
    
    // 读取每个节点的暴龙种类
    for(ll i = 1; i <= n; i++) cin >> a[i];
    
    // 读取树的边信息，并构建邻接表
    for(ll i = 1; i < n; i++){
        ll u, v, w;
        cin >> u >> v >> w;
        adj[u].emplace_back(v, w);
        adj[v].emplace_back(u, w);
    }
    
    // 从节点1开始DFS遍历整棵树，假设节点1为根节点，父节点为0
    dfs(0, 1);
    
    // 输出每种暴龙的红温值
    for(ll i = 1; i <= k; i++) cout << ans[i] << '\n';
}
